var fs = require('fs');
var https = require('https');
var http = require('http');
var request;
///下载文件
function downLoad(from,to,func){
  request = request || require('request');
  var writeStream = fs.createWriteStream(to);
  var readStream = request(from);
  readStream.pipe(writeStream);
  readStream.on('end', function() {
    
  });
  readStream.on('error', function(err) {
    console.log("错误信息:" + err);
    func({errorMsg:JSON.stringify(err)});
  })
  writeStream.on("finish", function() {
    writeStream.end();
    func({});
  });
}
///复制文件
function copyFile(from,to,replace,func,type){
  var pathArr = to.split('/'),file = pathArr[pathArr.length - 1];
  if(/\./.test(file)) pathArr.pop();
  var nowPath = '';
  for(var i = 0; i < pathArr.length; i ++){
    if(!pathArr[i]) continue;
    var p = nowPath ? '/' + pathArr[i] : (to.charAt(0) == '/' ? '/' + pathArr[i] : pathArr[i]);
    if (!fs.existsSync(nowPath + p)) fs.mkdirSync(nowPath + p);
    nowPath += p;
  }
  if(!/\./.test(file)) return false;
  var fromString = fs.readFileSync(from, type === false ? null : (type || 'utf-8'));
  if(typeof replace == 'object'){
    fromString = fileReplace(fromString,replace);
  }else if(typeof replace == 'function'){
    fromString = replace(fromString,from,to);
  }
  if(func) fromString = func(fromString);
  if(fromString == null || fromString == undefined) return;
  fs.writeFileSync(to, fromString);
}
///
function fileReplace(string,replace){
  if(typeof replace == 'function'){
    string = replace(string);
  }else if(replace && typeof replace == 'object'){
    for(var key in replace){
      switch(typeof replace[key]){
        case 'string':
          string = string.replace ? string.replace(new RegExp(key,'gmi'),replace[key]) : string;
          break;
        case 'function':
          string = replace[key](string,key);
          break;
        default:
          break;
      }
    }
  }
  return string;
}
///复制文件夹
function copyFolder(from,to,replace,func){
  if(!fs.existsSync(from)) return false;
  try{
    var files = fs.readdirSync(from);
    if(files && files.length){
      var pathArr = to.split('/'),file = pathArr[pathArr.length - 1];
      var nowPath = '';
      for(var i = 0; i < pathArr.length; i ++){
        if(!pathArr[i]) continue;
        var p = nowPath ? '/' + pathArr[i] : (to.charAt(0) == '/' ? '/' + pathArr[i] : pathArr[i]);
        if (!fs.existsSync(nowPath + p)) fs.mkdirSync(nowPath + p);
        nowPath += p;
      }
      for(var i = 0; i < files.length; i ++ ) {
        (function(i){
          if(files[i].indexOf('.') === -1){
            copyFolder(from + '/' + files[i],to + '/' + files[i],replace,func);
          }else{
            var type = /\.(text)|(js)|(css)|(html)|(json)|(wxml)|(wxss)|(axml)|(acss)$/.test(files[i]) ? 'utf-8' : undefined;
            var fromString = fs.readFileSync(from + '/' + files[i],type);
            if(typeof replace == 'object'){
              fromString = fileReplace(fromString,replace);
            }else if(typeof replace == 'function'){
              fromString = replace(fromString,from + '/' + files[i],to + '/' + files[i]);
            }
            if(func) fromString = func(fromString,from + '/' + files[i],to + '/' + files[i]);
            if(fromString == null || fromString == undefined) return;
            fs.writeFileSync(to + '/' + files[i], fromString);
          }
        })(i)
      }
    }
  }catch(e){
    console.log(from,to,e)
  }
}
///删除文件
function deleteFile(path) {
  if( fs.existsSync(path) ) fs.rmdirSync(path);
}
///删除文件夹
function deleteFolder(path) {
  var files = [];
  if( fs.existsSync(path) ) {
    files = fs.readdirSync(path);
    files.forEach(function(file,index){
      var curPath = path + "/" + file;
      if(fs.statSync(curPath).isDirectory()) { // recurse
          deleteFolder(curPath);
      } else { // delete file
          fs.unlinkSync(curPath);
      }
    });
    fs.rmdirSync(path);
  }
}
module.exports = {
  downLoad,
  copyFile,
  fileReplace,
  copyFolder,
  deleteFile,
  deleteFolder,
  proxy:function(options){
    if(Config.proxy){
      if(typeof options == 'string'){
        let oldUrl = options
        for(let key in Config.proxy){
          options = options.replace(key,Config.proxy[key])
        }
        if(options != oldUrl) console.log('代理:',oldUrl,options)
      }else if(options.url){
        let oldUrl = options.url
        for(let key in Config.proxy){
          options.url = options.url.replace(key,Config.proxy[key])
        }
        if(options.url != oldUrl) console.log('代理:',oldUrl,options.url)
      }
    }
    return options;
  },
  get:function(url,next,dataType){
    url = this.proxy(url)
    dataType = dataType || 'json';
    (url.indexOf('https://') == 0 ? https : http).get(url, function(response){
        var data = '';
        response.on('data', function(chunk){
            data += chunk;
        });
        response.on('end', function(){
          try{
            next(dataType == 'json' ? JSON.parse(data) : data);
            data = '';
          }catch(e){
            console.log(data,e)
            next({ errorMsg: 'GET数据格式错误' });
            data = '';
          }
        })
    })
  },
  // ajax:function(options,bodyString,next){
  //   options = this.proxy(options);
  //   bodyString = typeof bodyString == 'string' ? bodyString : JSON.stringify(bodyString);
  //   options.dataType = options.dataType || 'json';
  //   var _options = {
  //     hostname: options.hostname,
  //     port: options.port || 443,
  //     path: options.path,
  //     method: options.method || 'POST',
  //     headers: options.headers || {
  //         'Content-Type': options.contentType || 'application/json',
  //         'Content-Length': bodyString.length
  //       }
  //   };
  //   var req = (_options.port == 443 ? https : http).request(_options, function(response){
  //     response.setEncoding(options.encoding || 'utf8');
  //     var data = '';
  //     response.on('data', function(d){
  //       data += d;
  //     });
  //     response.on('end', function(){
  //       try{
  //         data = decodeURIComponent(data)
  //         next(options.dataType == 'json' ? JSON.parse(data) : data);
  //       }catch(e){
  //         next(data);
  //       }
  //     })
  //   });
  //   req.on('error', function(err){
  //     next({errorMsg:err.errno});
  //   });
  //   req.write(bodyString);
  //   req.end();
  // },
  fetch(options,args){
    if(typeof options == 'string' && args){
      options = {
        url: options,
        method: args.method || 'POST',
        headers: args.headers || {},
        data: args.data || args.body || {}
      }
    }
    options = this.proxy(options)
    request = request || require('request');
    return new Promise(next => {
      if(typeof options == 'string'){
        this.get(options,next)
      }else{
        options.dataType = options.dataType || 'json'
        options.headers = options.headers || {}
        options.headers['Content-Type'] =  options.headers['Content-Type'] || 'application/json'
        let body = options.data || options.body || {}
        request({
          url: options.url,
          method: options.method || 'POST',
          headers: options.headers || {},
          body: typeof body == 'string' ? body : JSON.stringify(body) 
        }, function (err, response, ret) {
          try{
            if(err){
              next({errorMsg:err.toString()})
            }else{
              next(typeof ret == 'string' && options.dataType == 'json' ? JSON.parse(ret) : ret)
            }
          }catch(e){
            console.log(err,ret,e)
            next({ errorMsg:'数据格式错误' })
          }
        })
      }
    })
  },
  buildXML:function(json){
    var xml2js = require('xml2js');
    var builder = new xml2js.Builder();
    return builder.buildObject(json);
  },
  parseXML:function(xml, fn){
    var xml2js = require('xml2js');
    var parser = new xml2js.Parser({ trim:true, explicitArray:false, explicitRoot:false });
    parser.parseString(xml, fn||function(err, result){});
  },
  parseRaw:function(){
    return function(req, res, next){
      var buffer = [];
      req.on('data', function(trunk){
        buffer.push(trunk);
      });
      req.on('end', function(){
        req.rawbody = Buffer.concat(buffer).toString('utf8');
        next();
      });
      req.on('error', function(err){
        next(err);
      });
    }
  },
  pipe:function(stream, fn){
    var buffers = [];
    stream.on('data', function (trunk) {
      buffers.push(trunk);
    });
    stream.on('end', function () {
      fn(null, Buffer.concat(buffers));
    });
    stream.once('error', fn);
  },
  mix:function(){
    var root = arguments[0];
    if (arguments.length==1) { return root; }
    for (var i=1; i<arguments.length; i++) {
      for(var k in arguments[i]) {
        root[k] = arguments[i][k];
      }
    }
    return root;
  },
  generateNonceString:function(length){
    var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var maxPos = chars.length;
    var noceStr = "";
    for (var i = 0; i < (length || 32); i++) {
      noceStr += chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return noceStr;
  }
}